package com.baosight.risk.common.quartz;

import com.baosight.risk.api.fltd.FltdProcessService;
import com.baosight.risk.common.aspects.factory.AsyncFactory;
import com.baosight.risk.common.email.service.EmailService;
import com.baosight.risk.common.manager.AsyncManager;
import com.baosight.risk.common.utils.HttpUtils;
import com.baosight.risk.common.utils.ReadProperties;
import com.baosight.risk.common.utils.StringUtils;
import com.baosight.risk.mapper.rire.RireRiskTargetMapper;
import com.baosight.risk.mapper.xtzy.XtzyRoleUserMapper;
import com.baosight.risk.mapper.zbaa.ZbaaTargetMapper;
import com.baosight.risk.mapper.zbaa.ZbaaTargetValueMapper;
import com.baosight.risk.service.rire.entity.RireRiskTarget;
import com.baosight.risk.service.system.entity.SysOperLog;
import com.baosight.risk.service.xtzy.entity.XtzyRoleUser;
import com.baosight.risk.service.zbaa.entity.ZbaaTarget;
import com.baosight.risk.service.zbaa.entity.ZbaaTargetValue;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * @description: 先行指标更新通知
 * @Author: LiuHaoNan
 * @Date:
 */
@Slf4j
@Component("leadingTargetSubscribeTask")
public class LeadingTargetSubscribeTask {

    @Autowired
    private FltdProcessService fltdProcessService;

    @Autowired
    private RireRiskTargetMapper rireRiskTargetMapper;

    @Autowired
    private ZbaaTargetMapper zbaaTargetMapper;

    @Autowired
    private XtzyRoleUserMapper roleUserMapper;

    @Autowired
    private EmailService emailService;

    @Autowired
    private ZbaaTargetValueMapper targetValueMapper;

    //判断先行指标是否有新数据    通过判断是否发送过订阅消息(扩展属性暂未定)     每天的定时任务来判断是否有新数据,有则发送
    public void testParams(String params, String jobId) throws Exception {
        getDataByDay(params, jobId);
    }

    //每天遍历数据   如果EXT2存在字段为空的数据   则把这些数据发送催办并且 更改为Y(若没法送过代办 则为空,发送过则为Y)
    private void getDataByDay(String params, String jobId) throws Exception {
        List<SysOperLog> logs = new ArrayList<>();
        Exception error = null;

        try {
            //判断T_RIRE_RISK_TARGET是否有EXT2为空的数据
            RireRiskTarget rireRiskTarget = new RireRiskTarget();
            List<RireRiskTarget> list = rireRiskTargetMapper.selectUnsentCount(rireRiskTarget);
            ArrayList<String> targetNoList = new ArrayList<>();
            //这里先给指标去调接口,获取指标的近期趋势,在下面的循环里直接获取
            if (!list.isEmpty()){
                for (RireRiskTarget target:list){
                    targetNoList.add(target.getTargetNo());
                }
            }
            //调用陆家伟python接口处理数据
            list = getTargetValueTrend(targetNoList);
            if (!list.isEmpty()){
                //循环数据  记得中间调用接口判断上行下行震荡稳定
                for (RireRiskTarget target:list){
                    String targetNo = target.getTargetNo();
                    ZbaaTarget zbaaTarget = new ZbaaTarget();
                    zbaaTarget.setTargetNo(targetNo);
                    List<ZbaaTarget> select = zbaaTargetMapper.select(zbaaTarget);
                    //再从指标的所属部门找出部门关联的风险管理员
                    ZbaaTarget zbaaTarget1 = select.get(0);
                    XtzyRoleUser xtzyRoleUser = new XtzyRoleUser();
                    xtzyRoleUser.setRoleName("一级单位风险管理员");
                    xtzyRoleUser.setCompCode(zbaaTarget1.getManageCompCode());
                    List<XtzyRoleUser> select1 = roleUserMapper.select(xtzyRoleUser);
                    //message:状态描述一下是否超过预警值，和指标近期走势，上行，下行，稳定
                    double standardValue = Double.parseDouble(target.getStandardValue());//标准值,预警值
                    double targetValue = Double.parseDouble(target.getTargetValue());//实际值,指标值

                    String checkFlag = targetValue - standardValue > 0 ? "；目前超出预警值" + (targetValue-standardValue) : "；目前低于预警值" + (standardValue - targetValue);
                    String message = "指标当前值:" + targetValue + "；预警值为" +
                            standardValue + checkFlag + "；指标近期走势：" + target.getExt3();

                    int status = emailService.sendEmail(select1.get(0).getUserCode(), "先行指标更新消息", message, null);
                    //邮件发送失败
                    if (status != 1) {
                        throw new Exception("邮件发送失败");
                    }
                }
            }

            logs.add(fltdProcessService.getLog("每日先行指标订阅信息异常定时任务执行成功", 0, "", jobId));
        }catch (Exception e){
            error = e;
            log.error("每日先行指标订阅信息异常！");
            logs.add(fltdProcessService.getLog("每日先行指标订阅信息异常定时任务执行失败", 1, e.getMessage(), jobId));
        }
        // 保存日志到数据库
        AsyncManager.me().execute(AsyncFactory.batchRecordOper(logs));
        if (error != null) {
            throw error;
        }
    }

    private List<RireRiskTarget> getTargetValueTrend(List<String> targetNoList) {
        JSONObject object = null;

        List<List<String>> queryDataList = new ArrayList<>();
        for (int i = 0; i < targetNoList.size(); i++) {
            //List<RireRiskTarget> valueList = new ArrayList<>();
            List<RireRiskTarget> valueList  = rireRiskTargetMapper.getHistory(targetNoList.get(i),100);

            System.out.println("size: "+valueList.size());
            List<String> result = new ArrayList<>();
            for (RireRiskTarget rireRiskTarget : valueList) {
                String value = rireRiskTarget.getTargetValue();
                //只取数字和小数点(可能存在:例 50.6%的数据)
                char[] chars = value.toCharArray();
                //String regex  = "([1-9]\\d*\\.?\\d*)|(0\\.\\d*[1-9])";
                StringBuffer stringBuffer = new StringBuffer();
                for(int j =0;j<chars.length;j++){
                    int num = chars[j];
                    if ((num > 47 && num < 58)||num == 46){
                        stringBuffer.append(chars[j]);

                    }
                }
                result.add(String.valueOf(stringBuffer));
            }
            queryDataList.add(result);
        }
        Map<String, Object> maps = new HashMap<>();
        maps.put("data", queryDataList);

        try {
            // 调用Python接口
            String url = ReadProperties.getValueString("python.threshold.url");
            String result = HttpUtils.sendJsonPost(url, JSONObject.fromObject(maps));

            if (StringUtils.isNotEmpty(result)) {
                object = JSONObject.fromObject(result);
                System.out.println("预测结果：" + result);

                //新增到扩展字段的趋势
                List<String> stabilityList = JSONArray.toList(object.getJSONArray("stability"), new String(), new JsonConfig());
                // 解析返回的数据结果，将结果更新到value表中
                // 获取当前指标最新的指标数据
                for (int i = 0; i < targetNoList.size(); i++) {
                    List<RireRiskTarget> targetValueList = rireRiskTargetMapper.getLastZbaaTargetInfo(targetNoList.get(i),  "1");

                    RireRiskTarget latestValue = CollectionUtils.isNotEmpty(targetValueList) ? targetValueList.get(0) : new RireRiskTarget();
                    latestValue.setExt3(stabilityList.get(i));
                    //latestValue.setExt2("Y");
                    latestValue.setUpdateTime(new Date());
                    rireRiskTargetMapper.updateByPrimaryKey(latestValue);
                }
            }else {
                throw new Exception("接口调用--趋势赋值失败");
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        //数据更新后再重新查找一遍返回结果集
        RireRiskTarget target = new RireRiskTarget();
        return rireRiskTargetMapper.selectUnsentCount(target);
    }
}
